package com.chinamsp.dydb.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import org.springframework.core.io.ClassPathResource;


/**
 * 数据库 
 * @author shifenghu
 *
 */
public class DBUtils {
	/**
	 * read 缓存
	 */
	private static Map<String, String> readCacheds = new HashMap<String, String>(64);
	
	/**
	 * 根据 特定 class path uri 获取文件内容，并支持缓存
	 * <p>
	 * 		该类会调用 ClassPathResource 来初始化读取
	 * </p>
	 * @param path 文件路径
	 * @param cached 是否支持缓存，如果经常使用，则需要支持
	 * @return 文件内容
	 * @see ClassPathResource
	 */
	public static String readByClasspath(String path, boolean cached){
		String result = null;
		//如果支持 cached，且缓存中存在，则直接输出
		if(cached && (result = readCacheds.get(path)) != null){
			return result;
		}
		//从文件中读取
		ClassPathResource resource = new ClassPathResource(path);
		try {
			InputStream in = resource.getInputStream();
			StringBuilder builder = new StringBuilder();
			byte[] buffer = new byte[1024];
			int l = -1;
			while((l = in.read(buffer)) != -1){
				builder.append(new String(buffer, 0, l));
			}
			result = builder.toString();
			//如果支持缓存，则放入缓存中
			if(cached){
				readCacheds.put(path, result);
			}
			in.close();
			return result;
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
	}
	
	/**
	 * 从 classpath中读取文件数据，并以留的形式输出
	 * <p>
	 * 		该类会调用 ClassPathResource 来初始化读取，该方法不会关闭 out 流，请自行close处理
	 * </p>
	 * @param path 文件路径，相对于 classpath
	 * @param out
	 */
	public static void readByClasspath(String path, OutputStream out){
		//从文件中读取
		ClassPathResource resource = new ClassPathResource(path);
		try {
			InputStream in = resource.getInputStream();
			byte[] buffer = new byte[1024];
			int l = -1;
			while((l = in.read(buffer)) != -1){
				out.write(buffer, 0, l);
			}
			out.flush();
			in.close();
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
	}
	/**
	 * 从 classpath 文件中读取文件数据，并以 byte[] 方式返回
	 * <p>
	 * 		这里读取的文件最好比较小，如果太大或者可能的话，尽量使用 {@link #readByClasspath(String, OutputStream)} 方法，以流的形式读取
	 * </p>
	 * @param path 文件路径，相对于 classpath
	 * @return
	 */
	public static byte[] readByClasspath(String path){
		//从文件中读取
		ClassPathResource resource = new ClassPathResource(path);
		try {
			byte[] bytes = new byte[resource.getInputStream().available()];
			resource.getInputStream().read(bytes);
			return bytes;
		} catch (IOException e) {
			throw new IllegalArgumentException(e);
		}
	}
}
